﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Dispatcher.Presenter;
using System.Threading;
using C2dmSharp.Server;
using ListIt.DAL;
using Dispatcher.Views;

namespace Dispatcher
{
    public partial class FrmMain : Form, IBackLogView, IActiveJobView, ITaxiView
    {
        #region Private Variables
        private BacklogPresenter _backlogPresenter;
        private GenericPresenter _activJobPresenter;
        private TaxiPresenter _taxiPresenter;
        private BackgroundWorker _backlogDSWorker;
        private C2dmService _c2dmService;
	    #endregion

        #region Constructors
        public FrmMain()
        {
            _c2dmService = new C2dmService(ProtocolConstants.C2DM_SENDER,
                        "Allan2010", ProtocolConstants.C2DM_APPLICATION);


            _c2dmService = new C2dmService(ProtocolConstants.C2DM_SENDER,
                        "Allan2010", ProtocolConstants.C2DM_APPLICATION);

            // setup messages
            _c2dmService.MessageSuccess += (C2dmMessageTransportResponse response) =>
            {
                Log(string.Format("Message sent: {0}: {1}", response.Message,
                    response.MessageId));
            };

            _c2dmService.MessageFailure += (MessageTransportException ex) =>
            {
                Log(string.Format("Message sent: {0}", ex.Message));
            };

            _c2dmService.Waiting += (DateTime waitUntil) =>
            {
                MessageBox.Show("Service told to back off until: " + waitUntil.ToString());
            };

            _c2dmService.Start();

            _backlogPresenter = new BacklogPresenter(this, _c2dmService);
            _activJobPresenter = new ActivJobPresenter(this);
            _taxiPresenter = new TaxiPresenter(this, _c2dmService);
            InitializeComponent();
        }     
        #endregion    

        #region IBackLogView Members

        public object BackLogDataSource
        {
            set {
                Invoke((MethodInvoker)delegate
                {
                    dataGridViewBacklog.DataSource = value;
                });
            }
        }        

        public object SummaryDataSource
        {
            set {
                Invoke((MethodInvoker)delegate
                {
                    dataGridViewSummary.DataSource = value;
                }); 
            }
        }

        public void SendJobTimeoutToDriver(string licenseNo)
        {
            _taxiPresenter.SendMessage(licenseNo, "A job has been sent to you, unfortunately, you have not responded within the reasonable timeframe and it has been forwarded to the next driver in queue. ");
        }

        #endregion

        #region IActiveJobView Members

        object IActiveJobView.ActiveJobDataSource
        {
            set {
                Invoke((MethodInvoker)delegate
                {
                    dataGridViewActive.DataSource = value; 
                }); 
            }
        }

        #endregion

        #region ITaxiView Members

        object ITaxiView.TaxiDatasource
        {
            get
            {
                return dataGridViewTaxi.DataSource;
            }
            set
            {
                Invoke((MethodInvoker)delegate
                {
                    dataGridViewTaxi.DataSource = value;
                });
            }
        }

        private void PresentGrids()
        {
            // only refresh grids if we dispatched a job. Otherwise no change to the job tables
            _backlogPresenter.Present();
            _activJobPresenter.Present();
            _taxiPresenter.Present();
        }

        private void backlogMenu_Opening(object sender, CancelEventArgs e)
        {
            deleteJobToolStripMenuItem.Enabled = dataGridViewBacklog.CurrentRow != null;
            miDispatchToDriver.Enabled = deleteJobToolStripMenuItem.Enabled;
        }

        private void miDelete_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("Are you sure you want to delete this job?", "Confirm",
                MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.No)
            {
                return;
            }

            List<JobBackLogModelView> jobs = ((List<JobBackLogModelView>)dataGridViewBacklog.DataSource);

            foreach (DataGridViewRow row in dataGridViewBacklog.SelectedRows)
            {
                JobBackLogModelView job = (JobBackLogModelView)row.DataBoundItem;
                _backlogPresenter.Delete(job);
            }

            // update the grid
            Thread thread = new Thread(delegate()
            {
                PresentGrids();
            });
            thread.Start();
        }

        private void FrmMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            //_c2dmService.Stop();
        }
        #endregion

        #region Static Fns
        #endregion

        private void dataGridView1_RowPrePaint(object sender, DataGridViewRowPrePaintEventArgs e)
        {
            // dataGridViewSummary.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.Pink;
        }

        private void FrmMain_Load(object sender, EventArgs e)
        {
            tmrDispatch.Enabled = true;
        }

        private void dataGridViewBacklog_RowPrePaint(object sender, DataGridViewRowPrePaintEventArgs e)
        {
            DateTime dt = Convert.ToDateTime(dataGridViewBacklog.Rows[e.RowIndex].Cells[2].Value);
            TimeSpan ts = DateTime.Now.Subtract(dt);
            Color rowColor = Color.White;
            if (ts.TotalMinutes > 10)
                rowColor = Color.Red;
            else if (ts.TotalMinutes > 5)
                rowColor = Color.Orange;

            dataGridViewBacklog.Rows[e.RowIndex].DefaultCellStyle.BackColor = rowColor;
        }

        private void tmrDispatch_Tick(object sender, EventArgs e)
        {
            tmrDispatch.Enabled = false;

            Thread thread = new Thread(delegate()
             {
                 try
                 {
                     _backlogPresenter.DispatchJobs();
                     PresentGrids();
                 }
                 finally
                 {
                     Invoke((MethodInvoker)delegate
                     {
                         tmrDispatch.Enabled = true;
                     });
                 }
             });
            thread.Start();
        }

        public void Log(string s)
        {
            if (lboxLog.InvokeRequired)
            {
                lboxLog.Invoke(new MethodInvoker(
                    delegate
                    {
                        if (lboxLog.Items.Count >= 500)
                        {
                            lboxLog.Items.RemoveAt(lboxLog.Items.Count - 1);
                        }

                        lboxLog.Items.Insert(0, string.Format("[{0}] - {1}", DateTime.Now, s));
                    }));
            }
            else
            {
                if (lboxLog.Items.Count >= 500)
                {
                    lboxLog.Items.RemoveAt(lboxLog.Items.Count - 1);
                }

                lboxLog.Items.Add(string.Format("[{0}] - {1}", DateTime.Now, s));
            }
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //_backlogPresenter.TearDown();
            Close();
        }

        private void sendTaxiMsgMenuItem_Click(object sender, EventArgs e)
        {
            tmrDispatch.Enabled = false;
            try
            {
                string msg = Microsoft.VisualBasic.Interaction.InputBox("Enter the message you want to send to the driver(s)", "Server Message");

                if (msg != "")
                {
                    foreach (DataGridViewRow row in dataGridViewTaxi.SelectedRows)
                    {
                        TaxiClass taxiRow = (TaxiClass)row.DataBoundItem;

                        _taxiPresenter.SendMessage(taxiRow.LicenseNo, msg);
                    }
                }
            }
            finally
            {
                tmrDispatch.Enabled = true;
            }
        }

        private void miDispatchToDriver_Click(object sender, EventArgs e)
        {
            if ((dataGridViewBacklog.SelectedRows.Count > 1) || (dataGridViewBacklog.SelectedRows.Count == 0)) {
                MessageBox.Show("You must have 1 selected row in order to perform this operation.");
                return;
            }

            tmrDispatch.Enabled = false;
            try
            {
                FrmDispatchToTaxi frm = new FrmDispatchToTaxi(_backlogPresenter,
                    (JobBackLogModelView)dataGridViewBacklog.SelectedRows[0].DataBoundItem);
                frm.ShowDialog();
            }
            finally
            {
                tmrDispatch.Enabled = true;
            }
        }
    }
}
 